import { transformRequest, transformResponse, catchError } from './common';
import { beforeSend, afterSend } from './hook';
import tokenSvc from '../token';
import axios from 'axios';

const instance = axios.create({
  timeout: 30 * 1000,
  baseURL: process.env.VUE_APP_API,
  headers: {
    'Content-Type': 'application/json',
  },
  // `withCredentials` 表示跨域请求时是否需要使用凭证
  withCredentials: false, // 默认值
  // `responseType` 表示服务器响应的数据类型，可以是 'arraybuffer', 'blob', 'document', 'json', 'text', 'stream'
  responseType: 'json', // 默认值
});

instance.interceptors.request.use(transformRequest, Promise.reject);


async function axiosCall(options) {
  // 检查是否是确认交易
  const isConfirm = tokenSvc.isConfirApi(options.url);
  // 忽略需要加密的接口

  try {
    beforeSend(options);
    if (isConfirm) {
      // 确认交易追加token
      const tokenName = tokenSvc.resolveToken(options.url);
      options.data = Object.assign(options.data || {}, { _tokenName: tokenName });
    }

    const result = await instance(options)
      .catch(catchError)
      .then(transformResponse);

    return result;
  } catch (err) {
    if (isConfirm) {
      // 确认交易需要重新刷新token
      await tokenSvc.refreshToken(options.url);
    }
    throw err;
  } finally {
    afterSend(options);
  }
}

export default {
  get: async function(url, options = { handleError: true }) {
    options.method = 'GET';
    options.url = url;
    options.params = options.query;
    return axiosCall(options);
  },
  post: async function(url, options = { handleError: true }) {
    options.method = 'POST';
    options.url = url;
    options.data = options.payload || {};
    return axiosCall(options);
  },
  // FormData格式
  postForm: async function(url, options = { handleError: true }) {
    options.method = 'POST';
    const formdata = new FormData();
    const data = options.payload || {};
    for (const key in data) {
      if (Object.hasOwnProperty.call(data, key)) {
        formdata.append(key, data[key]);
      }
    }
    options.headers = Object.assign({}, options.headers || {}, {
      'Content-Type': 'multipart/form-data',
    });
    options.url = url;
    options.data = formdata;
    return axiosCall(options);
  },
  postBlob: async function(url, options = { handleError: true }) {
    options.method = 'POST';
    options.url = url;
    options.data = options.payload;
    options.responseType = 'blob';
    return axiosCall(options);
  },
};
